;When you are building a structure in S.A.D., functions from this code
;are used.  These include, but are not limited to, starting up the building construction,
;and continuing it without interrupting the game.



;----------------------------------------------------------
;----------------------------------------------------------
;----------------------------------------------------------

; BEGINNING MODIFIERS SHOULD NOT MESS WITH THE
; CODE IN THIS FILE

;----------------------------------------------------------
;----------------------------------------------------------
;----------------------------------------------------------




AddObjectToGameBegin:


	SET Object_Ready_To_Add, (IY + flag)
	RES Menu_Mode, (IY + flag)
	SET Wait_Between_Presses, (IY + flag)
	RES Cursor_Bitmap_Done, (IY + Flag)

	ld a, c
	ld (BuildingSelected), a
	call Rotate_Cursor_Mode
	ret



;When the user first adds a structure, a wrench tile will display.  This code
;adds the building to the list of buildings a player has, and starts construction.
;Other functions continue construction.

	
;The building location is noted in tiles, not pixels.  So we need to convert
;MapX and MapY (measured in pixels) to TileX and TileY, measured in tiles of 16 x 16 pixels.

Construct_Building:


	;Now that our building has been placed,
	;we don't need to cursor to place it anymore.

	RES Object_Ready_To_Add, (IY + flag)


	RES Menu_Mode, (IY + flag)

	;Turn off the cursor	

	Call Rotate_Cursor_Mode

	


	
	di	;We don't want our building construction data contaminated until we take care of the list
		;of buildings under construction


	;Retrieve the type of building or upgrade
	;we are constructing

	ld a, (BuildingSelected)
	ld c, a

	;Find the tile the cursor was pointing to

	call Find_Tile_On_Map



	push hl			;Saves the tile location



	ld d, 0
	ld e, c
	
	;Each structure contains 32 bytes of data.  Multiplying de by 32 will bring us to the correct
	;structure data.

	ld a, 32
	call Multiply_DE_By_A

	ex de, hl
	ld hl, Operation_Center
	add hl, de
	
	ld bc, 3
	add hl, bc

	ld e, (hl)
	inc hl
	ld d, (hl)

	or a
	sbc hl, bc

	;HL points to the type of building: 32 x 32, 32 x 16, 16 x 16,
				;or 16 x 32

	push hl

	;Decrease the player's money, since the building
	;was purchased

	ld hl, (Player1 + Player_Money)
	sbc hl, de
	ld (Player1 + Player_Money), hl

	pop hl


	pop de			;DE contains the location in the tilemap where the
				;building is to be placed

	
	ld c, (hl)		;C will equal 0 if building is 32 x 32, 3 if building is 16 x 16, etc.
	ld b, 126		;The tile for a "wrench" (indicating a building under construction)
				;is tile 126.  We put b inside of hl to store the wrench tile.
				;Depending on the size of the building, there may be more than one
				;wrench icon added

	ex de, hl		;HL contains the tilemap location, de contains the building data
				;location


	call Add_Building_Tiles

Now_That_The_Building_Is_Being_Constructed

	inc de			;DE points to the building ID.  We lost that value when register
				;C was used, so we need it to find out what to store inside of
				;the data that stores the 200 buildings constructed.

;If we are constructing a new building,
;we need to put the building at the end of the list.
;If we are repairing a building, doing an upgrade, or adding
;a refinery processing unit, we don't need to put a building
;at the end of the list.  Instead, we find the current building
;being altered using Current_Building (since the building would
;have been selected by the cursor).
	
	ld hl, Structure_Locations
	ld a, (Building_Count)

;Each building requires a basic 4 bytes of data common to all
;buildings.

	rla
	rla




	ld b, 0
	ld c, a
	add hl, bc		

;HL points to the first empty building, in order to add a new
;building to the list of buildings.

	
;Start by storing where on the map (in tiles) the building is located,
;that is, if we are constructing a brand new building.

	ld a, (TileX)
	ld (hl), a
	inc hl
	ld a, (TileY)
	ld (hl), a
	inc hl

;Now copy the building ID...that is, which building we
;are refering to.

	ld a, (de)
	rlca \ rlca \ rlca \ rlca
	ld (hl), a
	inc hl
	ld (hl), 0
	
	ld hl, List_Of_Buildings_Under_Construction		
	ld a, (End_Of_List_Of_Buildings_Under_Construction)
	rla \ rla
	
	
	ld c, a

	add hl, bc		

;List_Of_Buildings_Under_Construction contains all buildings
;that are being constructed.  It is responsible for adding HP
;to a building until it reaches its maximum HP (meaning
;it is fully constructed)

;Building_Count is, of course, how many buildings we have.

	ld a, (Building_Count)	;Copy the HP, and time of construction

;The first item inside of our list of buildings under construction
;is where in the list of buildings our constructed building is.
;In the case of a building that is not being built fresh, 
;we stored a building already in the list.

	ld (hl), a
	inc hl

	;Now we copy the HP left, as well as the build time
	;information.
	
	inc de
	inc de
	inc de

	ex de, hl
	
	ld c, 3
	ldir


;If a fresh building is being built, we increase the number
;of buildings we have so that we can add a new building safely.
	
	ld hl, Building_Count
	inc (hl)
	ld hl, End_Of_List_Of_Buildings_Under_Construction
	inc (hl)

	
	call Updatemapfull


	ld	a,%00001000
	out	(3),a
	ld	a,%00001010
	out	(3),a

	ei
	ret




;This sub will scan the list of buildings and continue to construct each one.  When a building
;is finished constructing, the wrenches on the map will be replaced with tiles
;for the actual building.

Continue_Building_Construction:
	
	
	
	;Find out how many buildings are being built

	ld a, (End_Of_List_Of_Buildings_Under_Construction)
	or a
	jr nz, EmergencyLocalLabel4

	;If no buildings are being constructed, exit.
	
	ret

EmergencyLocalLabel4:

	;We use register B to hold the number of buildings
	;under construction, being repaired, etc.
	
	ld b, a
	



	ld hl, List_Of_Buildings_Under_Construction 	

;Start at the beginning of the list
;and scan through each building, one
;at a time

	;We need to start out one byte before the list of buildings
	;being built, because this is simply the way the code
	;works.
	
	dec hl			
	
_


	;Saves the value of how many buildings we have left to check.

	push bc

	inc hl
	inc hl		;Move to the number of HP left to construct
	ld d, (hl)


	inc hl
	ld e, (hl)	;Now DE is the number of HP left to construct
			;or repair.



	

	ld a, e
	or d

	jr nz, _

	call Building_Construction_Complete
		
;If HP left is zero, the building
;is finished constructing.


	jp ++_						


_

	inc hl	;Move to the time.  This will allow the program to see if it's
		;time to add another value of HP to the building
	
	;Adjusts the time left before adding 1 more HP to the building

	ld c, (hl)	;Register C contains the building time.  The upper four bits contains
			;the number to start at when the timer resets, and the lower four bits
			;contains the actual time before 1 more HP is added.

	ld a, c		;We need register A for arithmetic operations
	

	and %00001111	;Clear the upper four bits so we can see if the timer has finished counting
			;down

	jr z, Reset_Timer_And_Add_HP
	
	;Since the timer does not need to be reset, we just decrease it by one, and do not add
	;HP yet.

	dec c
	ld (hl), c	;Put the new time left inside of the 
			;place that we got the time from.
	jp _

Reset_Timer_And_Add_HP:

	;We lost the original value of our time in register A,
	;but it is still saved in register C.  Since
	;we need to do more "math" on the time, put it inside of
	;register A again.
	

	ld a, c  
	

	
	
	rrca		;Clear the lower four bits so that what we have left is the time
			;to reset to
	rrca
	rrca
	rrca	
	
	or c		;Incorporate the "restart" time into C
	
	;Puts the new time inside of the place where we got
	;our previous time from.	
	
	
	ld (hl), a

	;Since we need to add 1 HP to the building under construction, we decrease the HP
	;left to construct by 1.

	dec de		;DE still is holding the HP left to build
	dec hl		;Move HL to the position where the "HP Left" is in the data
	ld (hl), e
	dec hl
	ld (hl), d
	dec hl
	ld a, (hl)	;Register A contains the location in the list of buildings.

	ld bc, 3
	add hl, bc
	push hl


	ld hl, Structure_Locations
	rlca
	rlca
	ld b, 0
	ld c, a
	add hl, bc	;HL points to the TileX at the proper building

	ld c, 3
	add hl, bc		;HL points to the HP

	inc (hl)	;Increase the HP by 1
	jr nz, EmergencyLocalLabel3

	dec hl
	inc (hl)
	
	
	

EmergencyLocalLabel3:

	pop hl
_

	;Now check the next building being constructed
	
	pop bc
	ld a, b
	dec a
	ld b, a
	or a
	jp nz, ---_
	
	BIT Update_Map, (IY + flag + 1)

	jr nz, _


	ret	
_

	RES Update_Map, (IY + flag + 1)
	call updatemapfull
	


	
	ret




Building_Construction_Complete:		


	 RES Cursor_Over_Building, (IY + flag + 1)


					;If a building is finished, we remove it from the
					;list of buildings under construction, as well
					;as place the "finished product" on the tilemap.

	ld a, 1
	ld (Building_Finished), a 	;When it's time to place the building down,
					;the calculator will know that the tiles placed
					;are not wrench tiles, but rather actual structure
					;tiles.

	;Get the appropriate tile to draw at.

	;Start by looking at what part of the list of buildings the building is at

	dec hl
	dec hl
	ld a, (hl)

	rlca
	rlca

	ld b, 0
	ld c, a

	push hl				;Saves the location of buildings under construction, the location at the building finished
					;being built.
	

	ld hl, Structure_Locations



	add hl, bc


	inc hl


	;hl points to the proper building.  We look for the tile on the map, and then
	;search for the building's ID in order to draw the tiles on the map

	ld d, 0
	ld e, (hl)

	dec hl
	push hl

	ld c, (hl)

	ld a, (Mapwidth)
	call multiply_DE_By_A

	
	
	ld b, 0
	

	add hl, bc		;HL now contains the proper tile on the map.
	ld bc, Mapdata + 2
	add hl, bc
	
	pop de

	inc de
	inc de			;de points to the id of the building

	
	ld a, (de)
	and %11110000
	
	cp $50	;Refinery.  If a refinery has finished, we
		;need to increase the amount of crystals a player
		;mines.
	
	jr nz, ++_

	push hl
	push de

	ld hl, Player1 + Money_Per_Second

	inc (hl)


	;Also, we need to see if processing units are
	;being built.

	dec de
	dec de
	ex de, hl
	ld de, Structure_Tags - Structure_Locations
	add hl, de

	ld a, (hl)

	inc hl
	inc hl
	ld c, 50
	ld (hl), c
	dec hl
	dec hl

	or a	;If we want NO processing units--YET

	jr z, No_Want_Processing_Units

	push hl

	ld a, (hl)


	cp 9	;If a player has 9 or fewer processing
		;units, we can again increase the amount of
		;money a player is getting.  Meaning, the PU
		;mines 2 minerals per second.
		
	jr nc, _

Can_Add_Two_Crystals_Per_Minute:

	ld hl, Player1 + Money_Per_Second

	inc (hl)


_

	pop hl

	inc hl

	;If there are still more processing units that
	;we WANT to have, we need to construct at least one
	;more

	inc (hl)

	cp (hl)

	jr z, EmergencyLocalLabel12

	;Return to Structure_Locations so that
	;we can place another processing unit.

	or a

	dec hl
 	ld de, Structure_Tags - Structure_Locations
 	sbc hl, de

	call Start_Construction_Of_Processing_Unit

	jr EmergencyLocalLabel12

No_Want_Processing_Units:

	;Even if we have a basic, no-processing-unit
	;refinery, we can mine at 2 crystals per second

	ld hl, Player1 + Money_Per_Second

	inc (hl)


EmergencyLocalLabel12:

	pop de
	pop hl
	
_
	ld a, (de)

	and %11110000
	
	rla 

	ld b, 0
	rl b	


	ex de, hl
	
	;de contains the proper tile on the map.  We need HL to determine what tile to start drawing at, as
	;well as what kind of building to draw on the map.

	ld hl, Operation_Center

	ld c, a

	add hl, bc

	ld b, (hl)	;Now b contains the tile to draw at
	inc hl
	ld c, (hl)
	
	ex de, hl	;hl contains the proper tile on the map.
	


	call Add_Building_Tiles

	xor a
	ld (Building_Finished), a

	;Now that the building is finished constructing, let's remove it from the list of buildings under construction.
	;POP de as our destination to copy the remaining buildings to.  HL will become where to copy from.

	pop de
	push de

	ld b, d
	ld c, e
	
	inc bc \ inc bc \ inc bc \ inc bc




	ld a, (End_Of_List_Of_Buildings_Under_Construction)
	

	rlca \ rlca

	ld h,0
	ld l, a
	add hl, de
	or a			;Reset Carry Flag
	sbc hl, bc
	ld a, l
	or a
	jr nz, _
	ld a, h
	or a
	jr nz, _

	ld hl, End_Of_List_Of_Buildings_Under_Construction

	dec (hl)


	SET Update_Map, (IY + flag + 1)
	pop hl
	dec hl
	ret
_
	ld b, h
	ld c, l


	ld h, d
	ld l, e
	
	inc hl \ inc hl \ inc hl \ inc hl	
		
	


	ldir					;Now that building is emptied off the list.

	ld hl, End_Of_List_Of_Buildings_Under_Construction

	dec (hl)


						;Shaving down the list means the proper building is now the next
						;building to construct, so we don't want to accidentally move hl past that building.

	SET Update_Map, (IY + flag + 1)
	pop hl
	dec hl

	ret

	
	
	
Multiply_DE_By_A

	
	ld hl, 0		;hl will store the product
	ld b, 8			;check 8 bits
	
_

	rrca			;check bit 0 of register A
	jr nc, _

	add hl, de

_

	sla e
	rl d

	djnz --_
	ret





Add_Building_Tiles:

	
	;HL is the tile location on the map.  B is the tile to start at.

	ld (hl), b

	call Set_Collision_Building_Placed


	inc hl


	ld a, c
	cp 2	;16 x 32 building
	jr z, ++_
	cp 3	;16 x 16 building
	ret z

	ld a, (Building_Finished)
	or a
	jr z, EmergencyLocalLabel2

	


_
	inc b


EmergencyLocalLabel2:

	ld (hl), b
	call Set_Collision_Building_Placed
	
	ld a, c
	cp 1	;32 x 16 building
	ret z

	ld a, (Building_Finished)

	or a
	jr z, ++_
	inc b
	jr ++_

_



	ld a, (Building_Finished)
	or a
	jr z, EmergencyLocalLabel1	

	
	inc b
	

EmergencyLocalLabel1:




_

	ld a, (mapwidth)

	dec a


_	
	push bc
	ld c, a
	
	ld b, 0	

	add hl, bc		;Move on to the next row of the tilemap, since the structure takes
	pop bc			;up two rows.
	
	ld (hl), b
	call Set_Collision_Building_Placed
	ld a, c
	cp 2
	ret z

	ld a, (Building_Finished)
	or a
	jr z, _
	inc b

_
	inc hl
	ld (hl), b		
	call Set_Collision_Building_Placed
_	
	ret








Find_Tile_On_Map:

 ld de, (MapY)


 ld a, e		
 srl d \ rra
 srl d \ rra
 srl d \ rra
 srl d \ rra



	
 ld e, a
 ld a, (Cursor_Y)	

 rra \ rra \ rra \ rra

 add a, e

 ld (TileY), a


 ld e, a
 ld d, 0


 ld a, (MapWidth)

 Call multiply_de_by_a	;HL now contains the row of the tilemap data.  We need the column now
 
 ld de, (MapX)


 ld a, e
		
 srl d \ rra
 srl d \ rra
 srl d \ rra
 srl d \ rra

	
 ld e, a
 ld a, (Cursor_X)	

 rra \ rra \ rra \ rra

 add a, e

 ld (TileX), a

 ld e, a
 ld d, 0

 add hl, de

 ld de, Mapdata + 2

 add hl, de

 ret







Set_Collision_Building_Placed:

	push hl
	push de
	push bc

	ld d, h
	ld e, l

	
	ld bc, MapData + 2
	or a
	sbc hl, bc


	srl h \ rr l
	
	ld bc, MapTileConditions
	add hl, bc

	BIT 0, e
	jr nz, _
	SET 4, (hl)
	jr ++_

_
	SET 0, (hl)

_

	pop bc
	pop de
	pop hl

	ret
	
	